using System;
using System.Collections.Generic;
using System.Text;

namespace Decav.Reality
{
    /// <summary>
    /// A telephone number that can be formatted into various locale's phone numbers.
    /// </summary>
    [Serializable]
    public struct PhoneNumber
    {
        public PhoneNumber(string address)
        {
            if (address == null)
                throw new ArgumentNullException("address");

            StringBuilder builder = new StringBuilder(address.Length);

            // We don't need the leading 1 in a phone number (11 digits)
            address = address.Trim().TrimStart('+').TrimStart('1');

            foreach (char c in address)
            {
                if (ValidChars.IndexOf(c) != -1)
                    builder.Append(c);
            }

            _address = builder.ToString();

            if (_address.Length != 10)
                _address = string.Empty;
        }

        private const string ValidChars = "1234567890";
        private string _address;

        public static bool IsValid(string telNum)
        {
            if (telNum == null)
                return false;

            return new PhoneNumber(telNum)._address.Length == 10;
        }

        /// <summary>
        /// The empty phone number.
        /// </summary>
        public static readonly PhoneNumber Empty = new PhoneNumber();

        public override string ToString()
        {
            if (_address == null)
                return string.Empty;

            return _address.ToString();
        }

        public override int GetHashCode()
        {
            if (_address == null)
                return 0;

            return _address.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (obj.GetType() != typeof(PhoneNumber))
                return false;

            return ((PhoneNumber)obj)._address == _address;
        }

        public static implicit operator string(PhoneNumber address)
        {
            return address.ToString();
        }

        public static bool operator ==(PhoneNumber left, PhoneNumber right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(PhoneNumber left, PhoneNumber right)
        {
            return !left.Equals(right);
        }
    }
}
